vue-router 动态路由之权限控制
vue 项目的路由权限控制处理方法,借助于 vuex、vue-router 实现,因为每个人的需求不一致等问题,所以以下信息仅供参考。
参考文档 Vuex 模块化
创建以下文件
// router/router.js
/**
* 动态路由
* @type { *[] }
*/
export const asyncRouterMap = [
{
path: "/",
name: "index",
component: import("@/*******"),
redirect: "/home",
children: [
{
path: "/home",
name: "home",
component: import("@/*******"),
meta: {
title: "首页",
},
children: [
{
path: "/home",
name: "home",
component: () => import("@/*******"),
meta: {
title: "首页",
},
},
],
},
{
path: "/news",
name: "news",
component: import("@/*******"),
meta: {
title: "新闻列表页",
},
redirect: "/course/individualList",
children: [
{
path: "/news/list",
name: "newsList",
component: () => import("@/*******"),
meta: {
title: "列表页",
},
},
{
path: "/news/edit",
name: "newsEdit",
component: () => import("@/*******"),
meta: {
title: "编辑页",
permission: ["admin"], // 定义权限
},
},
],
},
],
},
];
/**
* 基础路由
* @type { *[] }
*/
export const constantRouterMap = [
{
path: "/user",
component: () => import("@/******"),
redirect: "/user/login",
hidden: true,
children: [
{
path: "login",
name: "login",
component: () => import("@/*******"),
},
],
},
];
// router/index.js
import Vue from "vue";
import Router from "vue-router";
import { constantRouterMap } from "./router.js";
Vue.use(Router);
export default new Router({
mode: "history",
routes: constantRouterMap,
});
// store/module/permission.js
import { asyncRouterMap, constantRouterMap } from "@/router/router.js";
import router from "@/router";
// 权限校验
function hasPermission(permission, route) {
if (
route.meta &&
route.meta.permission &&
Array.isArray(route.meta.permission)
) {
return route.meta.permission.some((e) => {
return permission.includes(e);
});
}
return false;
}
// 路由过滤
function filterAsyncRouter(routerMap, permissions) {
const accessedRouters = routerMap.filter((route) => {
if (hasPermission(permissions, route)) {
if (route.children && route.children.length) {
route.children = filterAsyncRouter(route.children, permissions);
}
return true;
}
return false;
});
return accessedRouters;
}
const permission = {
state: {
routes: constantRouterMap,
addRouters: [],
},
mutations: {
SET_ROUTERS: (state, routers) => {
state.addRouters = routers;
state.routes = routers.concat(constantRouterMap);
router.addRoutes(routers);
},
},
actions: {
GenerateRoutes({ commit }) {
return new Promise(async (resolve) => {
// 以下内容仅供参考,实际内容根据自己项目自定义
// 当前登录者权限 admin
const level = "admin";
if (["admin"].includes(level)) {
// admin 为最高权限,所以不做限制
commit("SET_ROUTERS", asyncRouterMap);
} else {
const initRouter = JSON.parse(JSON.stringify(asyncRouterMap));
const newRouter = filterAsyncRouter(initRouter, level);
commit("SET_ROUTERS", newRouter);
}
resolve();
});
},
},
};
export default permission;
// store/getters.js
const getters = {
addRouters: (state) => state.permission.addRouters,
};
export default getters;
// router/permission.js
import router from "./router";
import store from "./store";
const loginRoutePath = "/user/login"; // 登录页面
const defaultRoutePath = "/home"; // 默认页面
router.beforeEach((to, from, next) => {
let token = sessionStorage.getItem("token");
if (token) {
// 已登录
if (to.path === loginRoutePath) {
next({ path: defaultRoutePath });
} else {
if (!store.getters.addRouters.length) {
store.dispatch("GenerateRoutes").then(() => {
// 请求带有 redirect 重定向时,登录自动重定向到该地址
const redirect = decodeURIComponent(from.query.redirect || to.path);
if (to.path === redirect) {
next({ ...to, replace: true });
} else {
// 跳转到目的路由
next({ path: redirect });
}
});
} else {
next();
}
}
} else {
next(loginRoutePath); // 全部重定向到登录页
}
});
- 全局引入
// main.js
import store from "./store";
import router from "./router";
import "./router/permission";
new Vue({
router,
store,
render: (h) => h(App),
}).$mount("#app");
Powered by Waline v2.15.8